from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time


class BaseWait(object):
    def __init__(self, driver):
        self.driver = driver  # 示例化驱动
        self.time = time
        self.wait = WebDriverWait(self.driver, 20)  # 设置浏览器：driver 等待时间：20s,
        # WebDriverWait(driver, 超时时长, 调用频率, 忽略异常).until(可执行方法, 超时时返回的信息)

    def implicitly_wait(self, second=10):
        # implicitly_wait(xx)：设置等待时间为xx秒，等待元素加载完成，如果到了时间元素没有加载出，就抛出一个NoSuchElementException的错误。
        # 注意：隐性等待对整个driver的周期都起作用，所以只要设置一次即可。
        return self.driver.implicitly_wait(second)

    def sleep(self, second=2):
        # 默认2s强制等待：不管浏览器元素是否加载完成，程序都得等待3秒，3秒一到，继续执行下面的代码。
        return self.time.sleep(second)

    def presence_of_element_located(self, locator):
        # 设置判断条件：等待id='kw'的元素加载完成,相等返回True，否则返回False
        return self.wait.until(EC.presence_of_element_located(locator))

    def presence_of_all_elements_located(self, locators):
        # 判断所有元素是否加载完成,有一个满足即可，相等返回True，否则返回False
        return self.wait.until(EC.presence_of_element_located((locators)))

    def title_is(self, title):
        # 判断标题是否和预期的一致,符合返回True，否则返回False
        return self.wait.until(EC.title_is(title=title))

    def title_contains(self, title):
        # 判断标题中是否包含预期的字符串，符合返回True，否则返回False
        return self.wait.until(EC.title_contains(title=title))

    def visibility_of_element_located(self, locator):
        # 判断某个元素是否可见. 可见代表元素非隐藏，并且元素的宽和高都不等于0，符合返回True，否则返回False
        return self.wait.until(EC.visibility_of_element_located(locator))

    def visibility_of(self, element):
        # 判断元素是否可见，传入参数是定位后的元素WebElement,传入WebElement对象以及状态，相等返回True，否则返回False
        return self.wait.until(EC.visibility_of(element=element))

    def invisibility_of_element_located(self, locator):
        # 判断某个元素是否不可见，或是否不存在于DOM树，符合返回True，否则返回False
        return self.wait.until(EC.invisibility_of_element_located(locator))

    def text_to_be_present_in_element(self, locator, text):
        # 判断元素的 text 是否包含预期字符串，符合返回True，否则返回False
        return self.wait.until(EC.text_to_be_present_in_element(locator=locator, text_=text))

    def text_to_be_present_in_element_value(self, locator, text):
        # 判断元素的 text 是否包含预期字符串，符合返回True，否则返回False
        return self.wait.until(EC.text_to_be_present_in_element_value(locator=locator, text_=text))

    def frame_to_be_available_and_switch_to_it(self, locator):
        # 判断frame是否可切入，可传入locator元组或者直接传入定位方式：id、name、index或WebElement，符合返回True，否则返回False
        return self.wait.until(EC.frame_to_be_available_and_switch_to_it(locator=locator))

    def alert_is_present(self):
        # 判断是否有alert出现，符合返回True，否则返回False
        return self.wait.until(EC.alert_is_present())

    def element_to_be_clickable(self, locator):
        # 判断元素是否可点击，符合返回True，否则返回False
        return self.wait.until(EC.element_to_be_clickable(locator))

    def element_to_be_selected(self, by, element):
        # 判断元素是否被选中,一般用在下拉列表，传入WebElement对象，符合返回True，否则返回False
        return self.wait.until(EC.element_to_be_selected((by, element)))

    def element_located_to_be_selected(self, locator):
        # 判断元素是否被选中，符合返回True，否则返回False
        return self.wait.until(EC.element_located_to_be_selected(locator))

    def element_selection_state_to_be(self, element, is_selected):
        # 判断元素的选中状态是否和预期一致，传入参数：定位后的元素，相等返回True，否则返回False
        # self.wait.until(EC.element_selection_state_to_be(element=self.driver.find_element_by_id("peach"),is_selected = True))
        return self.wait.until(EC.element_selection_state_to_be(element=element, is_selected=is_selected))

    def element_located_selection_state_to_be(self, locator, is_selected):
        # 判断元素的选中状态是否和预期一致，传入参数：元素的定位，相等返回True，否则返回False
        return self.wait.until(EC.element_located_selection_state_to_be(locator=locator, is_selected=is_selected))

    def staleness_of(self, element):
        # 判断一个元素是否仍在DOM中，传入WebElement对象，可以判断页面是否刷新了
        return self.wait.until(EC.staleness_of(element=element))

    def element_wait_for_n(self,locator,num):
        """
        :rtype: object
        """
        # 判断一个元素是否存在，存在返回True，否则
        result = False
        for i in range(num):
            result = self.visibility_of_element_located(locator)
            if result:
                result = True
                break
            continue
        return result

    def element_wait_for(self,locator,timeout=10):
        # 一直等待某元素可见，默认10秒
        try:
            WebDriverWait(self.driver, timeout).until(EC.invisibility_of_element_located(locator))
            return True
        except TimeoutError:
            return False

